<?php

namespace app\api\model;

use app\admin\event\SystemLog;
use app\admin\model\Admin;
use think\db\Query;
use think\Model;
use think\Db;
use think\exception\DbException;
class OutStockModel extends Base
{

    protected static function init()
    {
        self::observe(SystemLog::class);
    }

    protected $table ='outstock';
    protected $field = ['id', 'status', 'number', 'create_time', 'kid', 'warehouse', 'maker', 'relation_number', 'type', 'des'];
    protected $autoWriteTimestamp = 'int';

    public function getTypeAttr($value)
    {
        //单据类型 1销售单 2配货单 3调拨单 4采购退货单
        switch ($value) {
            case 1:
                return '销售单';
            case 2:
                return '配货单';
            case 3:
                return '调拨单';
            default:
                return '采购退货单';
        }
    }

    public function getStatusAttr($value)
    {
        //状态 1待出库 2部分出库  3已出库 4已撤销
        switch ($value) {
            case 1:
                return '待出库';
            case 2:
                return '部分出库';
            case 3:
                return '已出库';
            default:
                return '已撤销';
        }
    }

    // 定义全局的查询范围
    protected function base($query)
    {
        $c = Admin::find(\app\http\GetUid::getUId());
        // 门店负责人可查看自己门店的所有信息
        if ($c->level == 2) {
            $maker = Admin::where('store', $c->store)->where('level', 3)->column('id');
        } elseif ($c->level == 1) {
            $maker = Admin::column('id');
        } else {
            $maker = $c->id;
        }
        $query->whereIn('maker', $maker);
    }

    public function getCreateTimeAttr($value)
    {
        return date('Y-m-d',$value);
    }
    /**
     * 出库单 列表
     * @return array|\PDOStatement|string|\think\Collection
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\ModelNotFoundException
     * @throws \think\exception\DbException
     */
    public function getOutList($data, $field = "", $order = "id desc")
    {
        $where =[];
        if ($data['start'] == 1) {
            if (!empty($data['status'])) {
                $where[] = ['o.status','=',$data['status']];
            } else {
                $where[] = ['o.status','in',[1,2,4]];
            }
        } else if ($data['start'] == 2) {
            if (!empty($data['status'])) {
                $where[] = ['o.status','=',$data['status']];
            } else {
                $where[] = ['o.status','in',[3,4]];
            }
        }
        if($data['start_time'] && $data['end_time']){
            $where[] =['o.create_time','between',[$data['start_time'],$data['end_time']]];
        }
        if(!empty($data['kid'])){
            $where[] = ['o.kid','=',$data['kid']];
        }
        if(!empty($data['warehouse'])){
            $where[] = ['o.warehouse','=',$data['warehouse']];
        }
        if(!empty($data['maker'])){
            $where[] = ['o.maker','=',$data['maker']];
        }
        if($data['number']){
            $where[] =['o.number','like','%'.$data['number'].'%'];
        }
        if(!empty($data['store'])){
            $where[] = ['a.store','=',$data['store']];
        }
        if(!empty($data['type'])){
            $where[] = ['o.type','=',$data['type']];
        }
        $list =Db::name('outstock')->alias('o')
            ->leftJoin('user u','u.id =o.kid')
            ->leftJoin('warehouse w','w.id =o.warehouse')
            ->leftJoin('admin a','a.id =o.maker')
            ->field('o.*,u.name as kid,w.name as warehouse,a.name as maker')
            ->where($where)->order('id desc')->page($data['page'],$data['size'])->paginate($data['size']);
        $list->each(function ($v) {
           $v['type_name'] = $this->getTypeAttr($v['type']);
           $v['create_time'] = $this->getCreateTimeAttr($v['create_time']);
            switch ($v['status']){
                case 1:
                    $v['status_name'] = "待出库";
                    $v['status2'] =27;
                    break;
                case 2:
                    $v['status_name'] = "部分出库";
                    $v['status2'] =28;
                    break;
                case 3:
                    $v['status_name'] = "已出库";
                    $v['status2'] =30;
                    break;
                default:
                    $v['status_name'] = "已撤销";
                    $v['status2'] =29;
                    $v['status3'] =31;
            }
           return $v;
        });
        return $list;
    }

    /**
     * 出库单 详情
     * @param $id
     * @return array|false|\PDOStatement|string|Model
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\ModelNotFoundException
     * @throws \think\exception\DbException
     */
    public function getInfo($id)
    {
        $list = $this->getOne('outstock','*',['id'=>$id]);
        if($list['type'] ==1){
            $current =$this->getOne('sale','*',['id'=>$list['relation_id']]);
            $list['goods'] =$this->getselectList('salerelation','*',['pid'=>$current['id']]);
        }else if($list['type'] ==2){
            $current =$this->getOne('prepare','*',['id'=>$list['relation_id']]);
            $list['goods'] =$this->getselectList('preparerelation','*',['pid'=>$current['id']]);
        }else if($list['type'] ==3){
            $current =$this->getOne('allot','*',['id'=>$list['relation_id']]);
            $list['goods'] =$this->getselectList('allotrelation','*',['pid'=>$current['id']]);
        }else{
            $current =$this->getOne('purchasereturn','*',['id'=>$list['relation_id']]);
            $list['goods'] =$this->getselectList('purchasereturnrelation','*',['pid'=>$current['id']]);
        }
        foreach($list['goods'] as $k=>$v){
            $dan =$this->getOne('product','commodity_id,color,size',['id'=>$v['product_id']]);
            $goods =$this->getOne('commodity','name,item,retail_price,goods_code,unit',['id'=>$dan['commodity_id']]);
            $list['goods'][$k]['commodity_id'] =$dan['commodity_id'];
            $list['goods'][$k]['name'] =$goods['name'];
            $list['goods'][$k]['item'] =$goods['item'];
            $list['goods'][$k]['price'] =$goods['retail_price'];
            $list['goods'][$k]['goods_code'] =$goods['goods_code'];
            $list['goods'][$k]['color'] =$this->getValue('color3',['id'=>$dan['color']],'name');
            $list['goods'][$k]['size'] =$this->getValue('color3',['id'=>$dan['size']],'name');
            $list['goods'][$k]['unit'] =$this->getValue('color1',['id'=>$goods['unit']],'name');
        }
        if(isset($list['kid'])){
            $list['kid_name'] =$this->getValue('user',['id'=>$list['kid']],'name');
        }
        $list['kid_name'] = $this->getValue('user', ['id' => $list['kid']], 'name');
        $list['kid_phone'] = $this->getValue('user', ['id' => $list['kid']], 'phone');
        $list['warehouse_name'] =$this->getValue('warehouse',['id'=>$list['warehouse']],'name');
        $user = $this->getOne('admin','name,phone',['id'=>$list['maker']]);
        $list['maker_name'] = $user['name'];
        $list['maker_phone'] = $user['phone'];
        $list['create_time'] = $this->getCreateTimeAttr($list['create_time']);
        return $list;
    }

    public function getDepot($id,$option)
    {
        $list =$this->getOne('outstock','*',['id'=>$id]);
        if($list['type'] ==1){//销售单
            $current =$this->getOne('sale','*',['id'=>$list['relation_id']]);
            $list['goods'] =$this->getselectList('salerelation','*',['pid'=>$current['id']]);
            foreach($list['goods'] as $k=>$v){
                foreach($option as $k1=>$v1){
                    if($v['id'] == $v1['id']){
                        if(isset($v1['num'])){
                            $list['goods'][$k]['num'] =$v1['num'];
                        }else{
                            throw new \Exception('请输入有效数量');
                        }
                    }
                }
            }
            $arr =[];
            foreach($list['goods'] as $k=>$v){
                if(isset($v['num'])) {
                    $yu = $v['put_number'] - $v['number'];//剩余待出库数量
                    //输入的数量大于剩余待出库数量
                    if ($v['num'] > $yu) {
                        throw new \Exception('超出库存上限');
                    } else if ($v['num'] < $yu) {
                        //输入的数量小于剩余待入库数量 部分出库
                        $arr[] = 1;
                    }
                    $this->getSetDec('product_stock', ['product_id' => $v['product_id'],'warehouse'=>$list['warehouse']], 'stock', $v['num']);
                    $this->getSetInc('salerelation', ['id' => $v['id']], 'number', $v['num']);
                    $this->getSetDec('product_stock', ['product_id' => $v['product_id'],'warehouse'=>$list['warehouse']], 'put_out', $v['num']);
                    $stock = $this->getValue('product_stock', ['product_id' => $v['product_id'],'warehouse'=>$list['warehouse']], 'stock');
                    $flow = [
                        'goods_id' => $v['product_id'],
                        'create_time' => time(),
                        'warehouse' => $list['warehouse'],
                        'type' => '销售单',
                        'number' => $list['number'],
                        'add_num' => '-' . $v['num'],
                        'sur_num' => $stock - $v['num']
                    ];
                    $this->getAdd('flowing_water', $flow);
                }
            }
            $payment =[
                'customer_id' => $current['kid'],
                'customer_type' => 'user',
                'maker' => $current['maker'],
                'set_account' => $current['set_account'],
                'account_type_id' => $current['type'],
                'in_amount' => $current['payment'],
                'des' => $current['des'],
                'create_time' => time(),
                'images' => $current['images'],
                'payment_mode' => $current['payment_mode'],
                'business_type' => '销售单',
                'business_number' => $current['number'],
                'business_time' => $current['create_time'],
            ];
            $this->getAdd('set_account_flow', $payment);
            if(count($arr) == count($list['goods']) || array_sum(array_unique($arr)) ==1){
                //部分出库
                $this->getSetField('sale',['id'=>$current['id']],['status'=>1]);
                $this->getSetField('outstock',['id'=>$id],['status'=>2]);
            }else{
                //全部出库
                $this->getSetField('sale',['id'=>$current['id']],['status'=>4]);
                $this->getSetField('outstock',['id'=>$id],['status'=>3]);
            }
        }else if($list['type'] ==2){//配货单
            $current =$this->getOne('prepare','*',['id'=>$list['relation_id']]);
            $list['goods'] =$this->getselectList('preparerelation','*',['pid'=>$current['id']]);
            foreach($list['goods'] as $k=>$v){
                foreach($option as $k1=>$v1){
                    if($v['id'] == $v1['id']){
                        if(isset($v1['num'])){
                            $list['goods'][$k]['num'] =$v1['num'];
                        }else{
                            throw new \Exception('请输入有效数量');
                        }
                    }
                }
            }
            $arr =[];
            foreach($list['goods'] as $k=>$v){
                if(isset($v['num'])) {
                    $yu = $v['put_number'] - $v['number'];//剩余待出库数量
                    //输入的数量大于剩余待出库数量
                    if ($v['num'] > $yu) {
                        throw new \Exception('超出库存上限');
                    } else if ($v['num'] < $yu) {
                        //输入的数量小于剩余待入库数量 部分出库
                        $arr[] = 1;
                    }
                    $this->getSetDec('product_stock', ['product_id' => $v['product_id'],'warehouse'=>$list['warehouse']], 'stock', $v['num']);
                    $this->getSetInc('preparerelation', ['id' => $v['id']], 'number', $v['num']);
                    $this->getSetDec('product_stock', ['product_id' => $v['product_id'],'warehouse'=>$list['warehouse']], 'put_out', $v['num']);
                    $stock = $this->getValue('product_stock', ['product_id' => $v['product_id'],'warehouse'=>$list['warehouse']], 'stock');
                    $flow = [
                        'goods_id' => $v['product_id'],
                        'create_time' => time(),
                        'warehouse' => $list['warehouse'],
                        'type' => '配货单',
                        'number' => $list['number'],
                        'add_num' => '-' . $v['num'],
                        'sur_num' => $stock - $v['num']
                    ];
                    $this->getAdd('flowing_water', $flow);
                }
            }
            $payment =[
                'customer_id' => $current['store'],
                'customer_type' => 'store',
                'maker' => $current['maker'],
                'in_amount' => $current['total'],
                'des' => $current['des'],
                'create_time' => time(),
                'images' => $current['images'],
                'business_type' => '配货单',
                'business_number' => $current['number'],
                'business_time' => $current['create_time'],
            ];
            $this->getAdd('set_account_flow', $payment);
            if(count($arr) == count($list['goods']) || array_sum(array_unique($arr)) ==1){
                //部分出库
                $this->getSetField('prepare',['id'=>$current['id']],['status'=>1]);
                $this->getSetField('outstock',['id'=>$id],['status'=>2]);
            }else{
                //全部出库
                $this->getSetField('prepare',['id'=>$current['id']],['status'=>4]);
                $this->getSetField('outstock',['id'=>$id],['status'=>3]);
            }
        }
        return 1;
    }

    /**
     * 出库单 撤销
     * @param $id
     * @return int
     */
    public function getRevoke($id)
    {
        $list =$this->getOne($this->table,'*',['id'=>$id]);
        if($list['type'] ==1){//销售单
            $this->getSetField('sale',['id'=>$list['relation_id']],['status'=>2]);
            $list['goods'] =$this->getselectList('salerelation','*',['pid'=>$list['relation_id']]);
            foreach($list['goods'] as $k=>$v){
                $this->getSetInc('product_stock',['product_id' => $v['product_id'],'warehouse'=>$list['warehouse']],'stock',$v['number']);
            }
        }else if($list['type'] ==2){//配货单
            $this->getSetField('prepare',['id'=>$list['relation_id']],['status'=>2]);
            $list['goods'] =$this->getselectList('preparerelation','*',['pid'=>$list['relation_id']]);
            foreach($list['goods'] as $k=>$v){
                $this->getSetInc('product_stock',['product_id' => $v['product_id'],'warehouse'=>$list['warehouse']],'stock',$v['number']);
            }
        }else if($list['type'] ==3){//调拨单
            $this->getSetField('allot',['id'=>$list['relation_id']],['status'=>3]);
            $current =$this->getOne('allot','*',['id'=>$list['relation_id']]);
            $current['goods'] =$this->getselectList('allotrelation','*',['pid'=>$list['relation_id']]);
            foreach($current['goods'] as $k=>$v){
                $this->getSetDec('product_stock',['product_id' => $v['product_id'],'warehouse'=>$current['call_in']],'stock',$v['put_number']);
                $this->getSetInc('product_stock',['product_id' => $v['product_id'],'warehouse'=>$current['call_out']],'stock',$v['put_number']);
            }
        }else{//采购退货单
            $this->getSetField('purchasereturn',['id'=>$list['relation_id']],['status'=>2]);
            $list['goods'] =$this->getselectList('purchasereturnrelation','*',['pid'=>$list['relation_id']]);
            foreach($list['goods'] as $k=>$v){
                $this->getSetInc('product_stock',['product_id' => $v['product_id'],'warehouse'=>$list['warehouse']],'stock',$v['put_number']);
            }
        }
        return $this->getSetField($this->table,['id'=>$id],['status'=>4]);
    }
}